#include "kddcup_feat.h"
#include "kddcup_spmat.h"
#include <cmath>
#include <vector>
#include <algorithm>

using namespace std;

static const int num_items = 6095;
static const int num_users = 2320895;

int nstar = 0;
int nhit = 0,  nmiss = 0;
int star_id[ num_users ];
SMatrix graph;

inline void load_star( const char *fname, int topn, int skiptop = 0 ){
    nstar = topn;
    int uid, lcnt = 0;
    FILE *fi = fopen_check( fname, "r" );
    while( fscanf( fi, "%d%*[^\n]\n", &uid ) == 1 ){
        if( lcnt < topn && lcnt >= skiptop ) star_id[ uid ] = lcnt - skiptop;
        lcnt ++;
    }
    fclose( fi );
}

inline void load_sns( const char *fname, int num_node = num_users ){
    SMatrix::Edge e;
    std::vector< SMatrix::Edge > data;
    FILE *fi = fopen_check( fname, "r" );
    while( fscanf( fi, "%d%d%*[^\n]\n", &e.from, &e.to ) == 2 ){
        if( star_id[ e.to ] != -1 ){
            e.to = star_id[ e.to ];
            data.push_back( e );
        }
    } 
    fclose( fi );
    graph.build( data, num_node );
}

inline void make_stats( FILE *fo, int uid ){
    SMatrix::Row row = graph[uid];
    fprintf( fo, "%d", row.nlen );
    if( row.nlen > 0 ){
        float inv = 1.0f / sqrtf( row.nlen );
        for( int i = 0; i < row.nlen; i ++ ){
            fprintf( fo, " %d:%f", row.index[i], inv );
        }
        nhit ++;
    }else{
        nmiss++;
    }
    fprintf( fo, "\n" );
}

int main( int argc, char* argv[] ) {
	if ( argc < 6 ) {
		printf("usage:<sns> <startlist> <train> <out> <topn> [skiptop]\n");
		return -1;
	}
    int skiptop = 0;
    if( argc > 6 ) skiptop = atoi( argv[6] ); 
    
    fill( star_id, star_id + num_users, -1 );
    load_star( argv[2], atoi( argv[5] ), skiptop );
    load_sns( argv[1] );

    int uid , uuid;
    FILE *fi = fopen_check( argv[3], "r" );    
    FILE *fo = fopen_check( argv[4], "w" );
    fprintf( fo, "%d\n", nstar - skiptop );
    assert_true( fscanf( fi, "%d%*d%*d%*d", &uid ) == 1, "BUG" );
    uuid = uid;
    while( uuid != -1 ){
        while( uuid == uid ){
            if( fscanf( fi, "%d%*d%*d%*d", &uid ) != 1 ){
                uid = -1;
            }
        }        
        make_stats( fo, uuid );        
        uuid = uid;
    }    
    fclose( fi ); fclose( fo );
    printf("all end, hit=%d/%d=%f\n", nhit, nmiss, (float)(nhit)/(nmiss+nhit) );
	return 0;
}
